package com.dangz.dans.netty;

import com.corundumstudio.socketio.AckRequest;
import com.corundumstudio.socketio.BroadcastOperations;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.annotation.OnConnect;
import com.corundumstudio.socketio.annotation.OnDisconnect;
import com.corundumstudio.socketio.annotation.OnEvent;
import com.dangz.dans.dao.ClientInfoRepository;
import com.dangz.dans.dao.ComUserRepository;
import com.dangz.dans.dao.MessageRepository;
import com.dangz.dans.model.ClientInfo;
import com.dangz.dans.model.Message;
import com.dangz.dans.model.User;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * 消息处理
 * @author dangz
 * @since 2018/6/25 11:37
 */
@Component
public class MessageEventHandler {
    private final SocketIOServer server;

    @Autowired
    private ClientInfoRepository clientInfoRepository;
    @Autowired
    private MessageRepository messageRepository;
    @Autowired
    private ComUserRepository userRepository;
    @Autowired
    public MessageEventHandler(SocketIOServer server) {
        this.server = server;
    }

    //添加connect事件，当客户端发起连接时调用，本文中将clientid与sessionid存入数据库
    //方便后面发送消息时查找到对应的目标client,
    @OnConnect
    public void onConnect(SocketIOClient client) {
//        String clientId = client.getHandshakeData().getSingleUrlParam("clientId");
        String userName = client.getHandshakeData().getSingleUrlParam("userName");
//        User user = userRepository.findOne(userName);
//        ClientInfo clientInfo = clientInfoRepository.findByClientId(clientId);
        ClientInfo clientInfo = new ClientInfo();
        Date nowTime = new Date(System.currentTimeMillis());
        clientInfo.setConnected(1L);
        clientInfo.setMostSignbits(client.getSessionId().getMostSignificantBits());
        clientInfo.setLeastSignbits(client.getSessionId().getLeastSignificantBits());
        clientInfo.setLastConnectedDate(nowTime);
        UUID uuid = new UUID(clientInfo.getMostSignbits(), clientInfo.getLeastSignbits());
        clientInfo.setUserId(userName);
        clientInfo.setClientId(uuid.toString());
//            client.joinRoom(user.getChatGroups()); //加入指定房间  群聊 或者群发(主要用于多方登陆的情况)
        clientInfoRepository.save(clientInfo);
//        server.getClient(uuid).sendEvent("connect", uuid);
    }

    //添加@OnDisconnect事件，客户端断开连接时调用，刷新客户端信息
    @OnDisconnect
    public void onDisconnect(SocketIOClient client) {
        //删除对应的客户端数据
//        System.out.println(client.getSessionId());
        client.disconnect();
        clientInfoRepository.deleteByClientId(client.getSessionId().toString());
    }

    //消息接收入口，当接收到消息后，查找发送目标客户端，并且向该客户端发送消息，且给自己发送消息
    @OnEvent(value = "messageEvent")
    public void onEvent(SocketIOClient client, AckRequest request, Message data) {
//        String targetClientId = data.getTargetClientId();
        String roomId = data.getRoomId();
        List<ClientInfo> infos = clientInfoRepository.findAllByUserId(data.getTo());
        /**
         * 封装消息保存到数据库
         */
        Message message = new Message();
        message.setCreateTime(new Date());
        message.setFrom(data.getFrom());
        message.setStatus(0);
        message.setType(data.getType());
        message.setTo(data.getTo());
        message.setContent(data.getContent());

        UUID uuid = null;
        //在线处理
        if (infos.size() > 0) {
            for (ClientInfo info : infos) {
                if (info != null && info.getConnected() != 0 && StringUtils.isEmpty(roomId)) {
                    uuid = new UUID(info.getMostSignbits(), info.getLeastSignbits());
                    message.setStatus(1);
                    server.getClient(uuid).sendEvent(data.getType(), message);
                } else {
                    //离线的处理方式
                    //目前只需保存消息内容，再次登录时 推送消息
                }
            }
        }
        //针对在线用户 在同一广播下  ，离线需单独处理
        if (StringUtils.isNotEmpty(roomId)){
            //返回默认名称空间的所有实例组成的广播对象 // 群发
            BroadcastOperations operations = server.getRoomOperations(roomId);
            Collection<SocketIOClient> allClients = operations.getClients();
            List<ClientInfo> clientInfos = clientInfoRepository.findAllByGreoupByUserId();
            for (SocketIOClient socket : allClients) {
                // 排除自己
                if (!socket.getSessionId().equals(client.getSessionId())) {
                    //判断具体某个用户
                    for (ClientInfo info : clientInfos) {
                        uuid = new UUID(info.getMostSignbits(), info.getLeastSignbits());
                        if (socket.getSessionId().equals(uuid)) {
                            message.setTo(info.getUserId());
                            messageRepository.save(message);
                        }
                    }
                    //给所有客户端发送消息
                    server.getClient(socket.getSessionId()).sendEvent(data.getType(), message);
                }
            }
        }
        if (StringUtils.isEmpty(roomId)) {
            client.sendEvent(data.getType(), message);
            messageRepository.save(message);
        }
    }
}